﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Office.Interop.Excel;

namespace ObjectModel.Excel
{
    /// <summary>
    /// Acts as a router for the events of an Excel worksheet and can be enabled or disabled independently.
    /// 
    /// Note: it is safe to subscribe a range to the events of a single worksheet
    /// as the worksheet property of an Excel range never changes, even if the
    /// physical range it originally referred to is moved to another worksheet/workbook.
    /// </summary>
    public class WorksheetEvents
    {
        List<ObservableRange> mSubscribedRanges = new List<ObservableRange>();
        bool mEnabled = true;
        
        public bool Enabled
        {
            get { return mEnabled; }
            set { mEnabled = value; }
        }

        private Worksheet Worksheet { get; set; }

        public WorksheetEvents(Worksheet worksheet)
        {
            Worksheet = worksheet;
            Worksheet.Change += Worksheet_Change;
            Worksheet.SelectionChange += Worksheet_SelectionChange;
        }

        public void Unsubscribe(ObservableRange range)
        {
            mSubscribedRanges.Remove(range);
        }

        public void Subscribe(ObservableRange range)
        {
            mSubscribedRanges.Add(range);
        }

        private void Worksheet_Change(Range Target)
        {
            if (!Enabled) return;

            foreach (ObservableRange range in mSubscribedRanges)
                range.OnWorksheetChanged();
        }

        private void Worksheet_SelectionChange(Range Target)
        {
            if (!Enabled) return;

            ObservableRange selectedRange = mSubscribedRanges.FirstOrDefault(r => r.Address == Target.Address);
            
            if (selectedRange != null)
                selectedRange.OnWorksheetSelectionChange(new EventArgs());
        }
    }
}
